package cn.sinjet.communication.bluetooth;
import com.mgroup.wazehelper.R;

import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import cn.sinjet.carassist.SinjetApplication;
import cn.sinjet.communication.bluetooth.LeBluetooth.LeBluetoothCallback;
import cn.sinjet.communication.bluetooth.SppBluetooth.SppBluetoothCallback;
import cn.sinjet.model.carsystem.CarModel;
import cn.sinjet.model.carsystem.WorkerThread;
import cn.sinjet.model.mcuupgrade.McuUpgradeModel;
import cn.sinjet.viewmodel.ViewModel;

public class BluetoothModel {
	private static final String tag = "BT";
	static private BluetoothModel mBTModel = null;
	LeBluetooth leBluetooth = null;
	SppBluetooth sppBluetooth = null;
	
	public static final int Mode_SPP = 0;
	public static final int Mode_BLE = 1;
//	public static final String BT_NAME = "toure";
	public static final String BT_NAME1 = "Sinjet";
	public static final String BT_NAME2 = "toure";
	private Context mContext = null;
	private int mBTState = BTState.DISCONNECTED;
	private int mBTMode =  Mode_SPP;
	WorkerThread workerThread = null;
	public BTWorkingHandler btWorkingHandler = null;
	private boolean mIsInit = false;
	public BluetoothModel(Context context){
		mContext = context;
		workerThread = new WorkerThread("BT_Working_Thread");
		btWorkingHandler = new BTWorkingHandler(workerThread.getLooper(),this);
		leBluetooth = new LeBluetooth(context);
		sppBluetooth = new SppBluetooth(context);
	}
	
	public static synchronized BluetoothModel getInstance(){
		if(mBTModel == null)
			mBTModel = new BluetoothModel(SinjetApplication.getInstance());
		return mBTModel;
	}
	
	public void setBTMode(int mode){
		mBTMode = mode;
	}
	
	public int getBTMode(){
		return mBTMode;
	}
	
	public void initBTModel(){
		  Message msg = btWorkingHandler.obtainMessage();
	      msg.what = BTWorkingHandler.MSG_INIT_BT;
	      btWorkingHandler.sendMessage(msg);
	}
	public void connectBT(){
		Message msg = btWorkingHandler.obtainMessage();
	      msg.what = BTWorkingHandler.MSG_CONNECT_BT;
	      btWorkingHandler.sendMessage(msg);
	}
	public void disconnectBT(){
		Message msg = btWorkingHandler.obtainMessage();
	      msg.what = BTWorkingHandler.MSG_DISCONNECT_BT;
	      btWorkingHandler.sendMessage(msg);
	}
	
	
	protected void initBTInThread(){//called in BT working thread 
		Log.d(tag, "init BTModel");
		
		if(mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
			if(leBluetooth.initLeBluetooth()){
	        	 mBTMode = Mode_BLE;
	        	 leBluetooth.setLeBluetoothCallback(mLeBluetoothCallback);
	        	 connectBTInThread();
	      	     mIsInit = true;
	         }
			return;
	    }
	
		Log.d(tag, "your phone does not support BLE");
	   boolean ret = sppBluetooth.initSppBluetooth();
	   if(!ret) Log.d(tag,"your phone does not support");
	   sppBluetooth.setSppBluetoothCallback(mSppBluetoothCallback);
	   mBTMode = Mode_SPP;
	   
	   connectBTInThread();
	   
	   mIsInit = true;
	}	
	
	
	  protected void connectBTInThread(){
		  if(mBTState == BTState.CONNECTED)
			  return;
//		  showBTStateHint(true);
		  if(mBTMode == Mode_BLE)
			  leBluetooth.requestConnect();
		  else 
			  sppBluetooth.requestConnect();
	  }
  
     protected void diconnectBTInThread(){
	  if(mBTMode == Mode_BLE)
		  leBluetooth.requestDisconnect();
	  else
		  sppBluetooth.requestDisconnect();
  }
  
     
      public void sendMessage(byte[] message){
    	if(!isConnected()) return;
		if (McuUpgradeModel.getInstance().isThreadFrameSendRun) {
			if (McuUpgradeModel.getInstance().enumUpgradeHexTypeWhat == 0) {
				if (!McuUpgradeModel.getInstance().isUpgradeFrameData(message)) {
					return;
				}
			}
		}
		
		/*final StringBuilder stringBuilder = new StringBuilder(message.length);
		for (byte byteChar : message)
			stringBuilder.append(String.format("%02X ", byteChar));
		Log.d(tag,"sendMessage: "+ stringBuilder.toString());*/

    	int msgLength = message.length;
    	int msgOffset = 0;
    	while (msgLength > 0)
    	{
    		int copyLength = msgLength;
    		if (copyLength > 20)
    		{
    			copyLength = 20;
    		}
    		byte[] messageSend = new byte[copyLength];
    		System.arraycopy(message, msgOffset, messageSend, 0, copyLength);
    		
    		msgOffset += copyLength;
    		msgLength -= copyLength;
    		
			Bundle bundle = new Bundle();
			bundle.putByteArray(BTWorkingHandler.KEY_BT_MSG, messageSend);
			Message msg = btWorkingHandler.obtainMessage();
			msg.what = BTWorkingHandler.MSG_SEND_BT;
			msg.setData(bundle);
			btWorkingHandler.msgBuffCount++;
			btWorkingHandler.sendMessage(msg);
    	}
      }
  
      
	  protected void sendMessageInThread(byte[] message){
//		  Log.d(tag,"final sendMessage len:"+message.length);
		  if(mBTMode == Mode_BLE){
			    leBluetooth.sendMessage(message);         		  
		  }else
			  sppBluetooth.sendMessage(message);
		  
	  }
  
	 
	  
	  
	  SppBluetoothCallback mSppBluetoothCallback = new SppBluetoothCallback() {
		@Override
		public void onBTStateChange(int state) {
			// TODO Auto-generated method stub
			BluetoothModel.this.onBTStateChange(state);
		}

		@Override
		public void onReceived(byte[] message, int len) {
			// TODO Auto-generated method stub
			Log.d("BT", "Spp BT onRecv");
			BluetoothModel.this.onReceived(message,len);
		}
	  };
	  
	  LeBluetoothCallback mLeBluetoothCallback = new LeBluetoothCallback() {
		
		@Override
		public void onReceived(byte[] message,int len) {
			// TODO Auto-generated method stub
			Log.d("BT", "Le BT onRecv");
			BluetoothModel.this.onReceived(message,len);
		}
		
		@Override
		public void onBTStateChange(int state) {
			// TODO Auto-generated method stub
			BluetoothModel.this.onBTStateChange(state);
		}
	};
	
	
	private void onBTStateChange(int state){
		Log.d(tag, "onBTStateChange: "+mBTState+" -> "+state);
		refreshHomeBTStatus(state);
//		autoHideShowBTHint(mBTState,state);
		mBTState = state;
	    if(BTState.DISCONNECTED == state)
		     CarModel.getInstance().devModule.onBTDisconnected();
	    
		switch(state){
		case BTState.CONNECTED:
			Log.d(tag, "onBT Connected!!!!!!: ");
			refreshBTStatusInMap(true);
			CarModel.getInstance().devModule.onBTConnected();
			McuUpgradeModel.getInstance().checkVersion();
			break;
		default:
			refreshBTStatusInMap(false);
			break;
		}
	}
	
	private void refreshBTStatusInMap(boolean bConnected){
		/*Log.d(tag,"showBTConnected: "+ bConnected);
		ViewModel.getIns().setViewProperty(R.id.bt_status_map, (int)((bConnected)?1:0));*/
	}
	private void onReceived(byte[] message,int len){
		CarModel.getInstance().onRecvMsgFromDevice(message, len);
	}
	
	
	private void refreshHomeBTStatus(int state){
		final int COLOR_GREY = 0xFF888888;
		final int COLOR_BLUE = 0xFF11B1F4;
		final int COLOR_YELLOW = 0xFFEFBE14;
//		final int COLOR_GREEN = 0x70F310;
		String strState = mContext.getResources().getString(R.string.disconnected);//"未连接";
		int color = COLOR_GREY;//grey
		int level = 0;
		switch(state){
		case BTState.SCANING:
			strState = mContext.getResources().getString(R.string.scanning);
			color = COLOR_YELLOW;
			level = 1;
			break;
		case BTState.NOT_FOUND:
			strState = mContext.getResources().getString(R.string.not_found);
			color = COLOR_YELLOW;
			level = 1;
			break;
		case BTState.DISCONNECTED:
			strState = mContext.getResources().getString(R.string.disconnected);
			color = COLOR_GREY;
			level = 0;
			break;
		case BTState.CONNECTING:
			strState = mContext.getResources().getString(R.string.connecting);
			color = COLOR_YELLOW;
			level = 1;
			break;
		case BTState.CONNECTED:
			strState = mContext.getResources().getString(R.string.connected);
			color = COLOR_BLUE;
			level = 2;
			break;
		}
		ViewModel.getIns().setViewProperty(R.id.home_bt_status_img, level);
		ViewModel.getIns().setViewProperty(R.id.home_bt_status_text, strState);
		ViewModel.getIns().setViewProperty(R.id.home_bt_status_text, color);
	}
    public void clearBTMode(){
        if(mBTMode == Mode_BLE)
        	 leBluetooth.clearBT();
        else
        	sppBluetooth.clearBT();
        mIsInit = false;
    }

	public boolean isConnected() {
		// TODO Auto-generated method stub
		return (mBTState==BTState.CONNECTED)?true:false;
	}

	public void tryToKeepConnected() {
		// TODO Auto-generated method stub
		Log.d(tag, "onBackToMyScreen");
		Message msg = btWorkingHandler.obtainMessage();
	      msg.what = BTWorkingHandler.MSG_KEEP_CONNECTED;
	      //btWorkingHandler.msgBuffCount++;
	      btWorkingHandler.sendMessage(msg);
	}
	
	
	public void tryToKeepConnectedInThread() {
		// TODO Auto-generated method stub
		if(!isBTPowerOn()) return;
		Log.d(tag, "tryToKeepConnected BT");
        if(mIsInit){
			if(mBTMode == Mode_BLE){
				leBluetooth.tryToKeepConnected();
			}else{
				sppBluetooth.tryToKeepConnected();
			}
        }else{
        	initBTModel();
        }
			
	}
	
	BluetoothAdapter mBluetoothAdapter = null;
	private boolean isBTPowerOn(){
		if(mBluetoothAdapter == null){
			mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		}
	   if(mBluetoothAdapter != null)
		   return mBluetoothAdapter.isEnabled();
	   return false;
	}
}
